from concurrent.futures import ThreadPoolExecutor
from queue import Queue
from rtsplib_cpu.Rtsp import *

import threading, av, cv2, time, os
import redis
import logging


class GetRtspData:
    def __init__(self, url, pool, camera_id, retained_time, logger, iframe_flag):
        self.codec = av.CodecContext.create('h264', 'r')
        self.rtsp_url = url
        # self.rtsp = Rtsp.PyRtsp()
        self.rtsp = PyRtsp()
        print('iframe_flag'+iframe_flag)
        self.rtsp.onlyUseIFrame(False)
        self.pool = pool
        # redis数据保存时间
        self.retained_time = retained_time
        # 日志对象
        self.logger = logger
        # 相机 id
        self.camera_id = camera_id
        self.now_time_sort = 0
        self.now_index = 0
        self.queueTmp = Queue()

        self.key = ''
        self.cacheData = {}
        self.thread_pool = ThreadPoolExecutor(max_workers=20)
        # print(self.rtsp.version())

    def __enter__(self):
        return self

    def __exit__(self, exc_t, exc_v, traceback):
        self._close()

    def __del__(self):
        self._close()

    def _close(self):
        self.thread_pool.shutdown(wait=True)
        print('_close')

    def openUrl(self, url):
        self.rtsp.OpenUrl(str(url), str(url))
        # thread1 = threading.Thread(target=self.threadOpenUrl, args=(url,))
        # thread1.start()

    def StartPlay(self):
        try:
            self.openUrl(self.rtsp_url, )
            r = redis.Redis(connection_pool=self.pool)
            i = 0
            while True:
                info = self.rtsp.getQueueInfo()

                if (info.getBufferSize() == 0):
                    if (i == 0):
                        i = int(time.time())
                        # self.logger.info('i if ' + str(getNowCpu()) + str(getNowMem()) )
                    else:
                        nextTime = int(time.time())
                        self.logger.info(
                            'nextTime - i =' + str(nextTime - i) + str() + str(getNowCpu()) + str(getNowMem()))
                        if ((nextTime - i) >= 10):
                            self.logger.info('i if else if 1 ' + str(nextTime))
                            exception = 1 / 0
                    continue
                self.logger.info('BufferSize: ' + str(info.getBufferSize()))
                i = 0
                if (len(str(info.getSecondTime())) != 13):
                    self.logger.info('time error: ' + str(info.getSecondTime()))
                    continue
                camera_second_time = int(info.getSecondTime() / 1000)
                camera_millisecond_time = info.getSecondTime() + info.getMillisecondTime()
                if self.now_time_sort == 0:
                    self.now_time_sort = camera_millisecond_time
                    now_time = int(str(self.now_time_sort) + '0')
                else:
                    if self.now_time_sort == camera_millisecond_time:
                        self.now_index = self.now_index + 1
                        now_time = int(str(camera_millisecond_time) + str(self.now_index))
                        self.now_time_sort = camera_millisecond_time
                    else:
                        self.now_index = 0
                        self.now_time_sort = camera_millisecond_time
                        now_time = int(str(camera_millisecond_time) + '0')

                key = str(self.camera_id) + '_' + str(camera_second_time)
                # key
                if self.key != key:
                    cache_data_tmp = self.cacheData.copy()

                    # obj = {
                    #     "key": key,
                    #     "value": cache_data_tmp,
                    #     "camera_second_time": camera_second_time
                    # }
                    # self.queueTmp.put(obj)

                    # init
                    self.cacheData = {}
                    self.thread_pool.submit(self.saveRedis, self.key, cache_data_tmp, camera_second_time)
                    self.key = key

                self.cacheData[info.getBuffer()] = now_time
        except Exception as e:
            self.logger.exception('StartPlay: ' + str(e))
            return

    def saveRedis(self, key, cache_data, camera_second_time):
        # start = time.time()
        # print(cache_data)
        # file_size = len(cache_data) / 1000
        # self.logger.exception('file_size: '+str(file_size))
        r = redis.Redis(connection_pool=self.pool)
        r.zadd(key, cache_data)
        r.expire(key, self.retained_time)
        r.set(self.camera_id, camera_second_time)
        r.close()
        # end = time.time()
        # self.logger.exception('save time:' + str(start) + '-' + str(end) + '=' + str(end - start))
